import NetInfo from '@react-native-community/netinfo'
import BaseTools from "../utils/BaseTools";
import CodeTools from '../utils/Tools';
import IP from './host'
import Constant from './../../constant/Constant'
import { router } from 'expo-router';

// * 对象转 Map
export const obj2Map = (obj: object): Map<string, any> => {
    let params = new Map();
    for (var key in obj) {
        params.set(key, obj[key]);
    }
    return params;
}

// * Map 格式化 Get 请求参数
export const getParams = (map: any): string => {
    let params = '';
    for (let key of map) {
        params += '&' + key[0] + '=' + key[1];
    }
    return params.replace('&', '?');
}

// ? 日志请求
export const requestLog = async (logIP: RequestInfo, params: any): Promise<void> => {
    try {
        params.plat = '希漫阁'
        fetch(logIP, {
            headers: {
                'Content-Type': 'application/json'
            },
            method: 'POST',
            body: JSON.stringify(params)
        }).catch(e => { })
    } catch (e) {
        console.log('log-IP :>> ', JSON.stringify(e))
    }
}

export const logFun = (logIP: string, url: string, method: string, params: any, data: any) => {
    logIP && requestLog(logIP, {
        url,
        method,
        params,
        response: data
    })
}
// 返回处理
const handleFunc = (resolve: Function, reject: Function, responseData: any) => {
    const { code = 500, message = '服务异常~' } = responseData || {}
    return code == 0 ? resolve(responseData) : reject({ code, message })
}
// 异常处理
const errorFunc = async (err: any, reject: Function) => {
    const { code = 500, message = '服务异常~' } = err || {}
    if (code === 401) {
        return router.replace('/')
    }
    reject({ code, message });
}
// 网络提示
const isConnect = () => {
    return new Promise(async (resolve, reject) => {
        const [err, state] = await BaseTools.to(NetInfo.fetch())
        if (err) {
            return reject('网络异常')
        }
        if (state.isConnected) {
            resolve('')
        } else {
            BaseTools.showInfo('当前设备无网络~')
            reject('当前设备无网络')
        }
    })
}
// 调试功能
export const debugFun = () => {
    return new Promise(async (resolve) => {
        const [err, userInfo] = await CodeTools.getLocalStore(Constant.LOGIN_TOKEN_KEY)
        const [jsonErr, json] = CodeTools.toJson(userInfo)
        resolve({ logIP: IP.log_ip, token: json?.token, host: IP.server_ip })
    })
}
// 请求方法
export const api = async (method: string, url: string, params: any = ''): Promise<Response> => {
    method = method.toLocaleUpperCase()

    const [netErr, _] = await BaseTools.to(isConnect())
    if (netErr) {
        return Promise.reject(netErr)
    }

    const [debugErr, debug] = await BaseTools.to(debugFun())

    const { token = '', host = '', logIP = '' } = debug || {}

    // 请求头
    const headers = {
        Accept: 'application/json',
        'Content-Type': 'application/json',
    }
    token && (headers['Authorization'] = 'Bearer ' + token)

    let requestUrl = host + url,
        requestBody: object = {
            method,
            headers,
        }

    if (method === 'GET') {
        if (params && params instanceof Object) {
            requestUrl += getParams(obj2Map(params));
        }
    } else {
        params = JSON.stringify(params)
        if (params) {
            requestBody['body'] = params
        }
    }
    return new Promise((resolve, reject) => {
        fetch(requestUrl, requestBody)
            .then(response => response.json())
            .then(responseData => {
                logFun(logIP, requestUrl, method, params, responseData)
                return handleFunc(resolve, reject, responseData)
            })
            .catch((err) => {
                logFun(logIP, requestUrl, method, params, err)
                return errorFunc(err, reject)
            })
    })
}
